/* Copyright (c) [2024] [ylc]. Licensed under Apache-2.0 License. */

#include "i2cDriveS.h"

//io口模拟i2c从机
//共5个操作IO函数和1个回调函数需要实现

void i2c_Sda_H_Cb(sI2CTypedef_t* i2c)
{
    if (i2c->IIC_READ_SCL()) {		//停止信号
        i2c->Sta = IIC_S_STA_IDLE;
        i2c->IIC_CALLBACK(IIC_S_IT_IDLE);
    }

}

void i2c_Sda_L_Cb(sI2CTypedef_t* i2c)
{
    if (i2c->IIC_READ_SCL()) {		//起始信号
        if (i2c->Sta != IIC_S_STA_ACK_END && i2c->Sta != IIC_S_STA_SEND) {  
            i2c->Sta = IIC_S_STA_RECV;
			i2c->IIC_CALLBACK(IIC_S_IT_START);
            i2c->BitId = 0;
            i2c->RxLen = 0;
        }
    }
}

//scl变高，此时应该读取电平
void i2c_Scl_H_Cb(sI2CTypedef_t* i2c)
{
    if (i2c->Sta == IIC_S_STA_RECV) {   //接收数据
        i2c->Value <<= 1;
        i2c->Value |= i2c->IIC_READ_SDA();
        i2c->BitId++;
        if (i2c->BitId >= 8) {
            i2c->RxLen++;
            if (i2c->RxLen == 1) {      //iic接收的第一个字节是7位设备地址+1位读写标识
                i2c->DevAddrGet = i2c->Value;
                if ((i2c->DevAddrGet & 0xFE) == i2c->DevAddrSet) {
                    i2c->Sta = IIC_S_STA_ACK;
                }
                else {
                    i2c->Sta = IIC_S_STA_PEND;
                    //i2c->Sta = IIC_S_STA_ACK;   //不论地址是什么都回复
                }
            }
            else {
                i2c->Sta = IIC_S_STA_ACK;
            }
            i2c->IIC_CALLBACK(IIC_S_IT_RECV);
        }
    }
    else if (i2c->Sta == IIC_S_STA_WACK) {       //等待ack
        if (i2c->IIC_READ_SDA() == 0) {
            i2c->Sta = IIC_S_STA_ACK_END;
        }
        else {	//NACK
            i2c->Sta = IIC_S_STA_PEND;
            i2c->IIC_CALLBACK(IIC_S_IT_PEND);
        }
    }
}

//scl变低，此时应该改变电平
void i2c_Scl_L_Cb(sI2CTypedef_t* i2c)
{
    if (i2c->Sta == IIC_S_STA_ACK) {            //回复ACK
        i2c->IIC_SDA_L();	//ACK
        i2c->Sta = IIC_S_STA_ACK_END;
    }
    else if (i2c->Sta == IIC_S_STA_ACK_END) {   //ACk结束
        if ((i2c->DevAddrGet & 0x01)) {	    //主机读
            i2c->Sta = IIC_S_STA_SEND;
            i2c->IIC_CALLBACK(IIC_S_IT_SEND);	//填数据到缓冲 此处发送中断
            if (i2c->Value & 0x80) {
                i2c->IIC_SDA_H();
            }
            else {
                i2c->IIC_SDA_L();
            }
            i2c->Value <<= 1;
            i2c->BitId = 1;
        }
        else {							//主机写
            i2c->IIC_SDA_H();	    //释放总线
            i2c->Sta = IIC_S_STA_RECV;
            i2c->BitId = 0;
        }
    }
    else if (i2c->Sta == IIC_S_STA_SEND) {
        if (i2c->BitId < 8) {
            if (i2c->Value & 0x80) {
                i2c->IIC_SDA_H();
            }
            else {
                i2c->IIC_SDA_L();
            }
            i2c->Value <<= 1;
            i2c->BitId++;
        }
        else {
            i2c->IIC_SDA_H();
            i2c->Sta = IIC_S_STA_WACK;
        }
    }
}


